package wang.aweb.childcar.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import io.netty.bootstrap.ServerBootstrap;
import io.swagger.models.auth.In;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;
import wang.aweb.childcar.exception.CarException;
import wang.aweb.childcar.exception.CarExceptionEnum;
import wang.aweb.childcar.model.dao.DeviceMapper;
import wang.aweb.childcar.model.pojo.Agent;
import wang.aweb.childcar.model.pojo.Device;
import wang.aweb.childcar.model.query.DeviceParam;
import wang.aweb.childcar.model.req.FenceDeviceReq;
import wang.aweb.childcar.model.req.IdReq;
import wang.aweb.childcar.model.vo.AgentVO;
import wang.aweb.childcar.model.vo.DeviceVO;
import wang.aweb.childcar.service.AgentService;
import wang.aweb.childcar.service.DeviceService;
import wang.aweb.childcar.tcpserver.NettyServer;
import wang.aweb.childcar.tcpserver.ServerHandler;
import wang.aweb.childcar.util.MonthDataUtils;

import java.util.*;

@Service
public class DeviceServiceImpl implements DeviceService {
    @Autowired
    private DeviceMapper deviceMapper;
    @Autowired
    private AgentService agentService;

    /**
     * 启用或禁用设备
     * @param id 设备ID
     */
    public void disableOrEnable(Integer id){
        Device currentDevice=deviceMapper.selectByPrimaryKey(id);
        Device deviceNew=new Device();
        deviceNew.setId(id);
        if(currentDevice.getStatus()==3){
            deviceNew.setStatus(1);
        }else{
            deviceNew.setStatus(3);
        }
        int count=deviceMapper.updateByPrimaryKeySelective(deviceNew);
        if(count==0){
            throw new CarException(CarExceptionEnum.UPDATE_FAILED);
        }
    }
    @Override
    public List<DeviceVO> getAll(){
        List<Device> deviceList=deviceMapper.selectAll();
        List<DeviceVO> deviceVOList=deviceListToDeviceVOList(deviceList);
        return deviceVOList;
    }

    @Override
    public List<Device> getListByFenceId(Integer id) {
        List<Device> deviceList=deviceMapper.selectByFenceId(id);
        return deviceList;
    }
    @Override
    public List<Device> selectByAgentId(Integer id){
        List<Device> deviceList=deviceMapper.selectByAgentId(id);
        return deviceList;
    }
    @Override
    public Integer getAgentDeviceCount(Integer agentId, Date starttime, Date endtime){
        Integer count=deviceMapper.getAgentDeviceCount(agentId,starttime,endtime);
        return count;
    }
    @Override
    public Integer getDeviceCount(){
        Map<String, Integer> param=new HashMap<>();
        param.put("status",null);

        Integer count=deviceMapper.getCount(param);
        return count;
    }
    @Override
    public Integer getFreeCount(){
        Map<String, Integer> param=new HashMap<>();
        param.put("status",1);
        Integer count=deviceMapper.getCount(param);
        return count;
    }
    @Override
    public void setDeviceFenceIds(FenceDeviceReq fenceDeviceReq) {
        int[] deviceIdS=fenceDeviceReq.getDeviceids();
        Integer fenceId=fenceDeviceReq.getFenceid();
        List<Device> deviceList=getListByFenceId(fenceId);
        List<Integer> alreadyIds=new ArrayList<>();
        for(Device device:deviceList){
            alreadyIds.add(device.getId());
            boolean flag=false;
            for(int deviceId:deviceIdS){
                if(deviceId==device.getId()){
                    flag=true;
                }
            }
            if(flag==false){
                setDeviceFenceIdNone(device);
            }
        }
        for(int deviceId:deviceIdS){
            if(!alreadyIds.contains(deviceId)){
                fenceDeviceReq.setDeviceid(deviceId);
                setDeviceFenceId(fenceDeviceReq);
            }
        }
    }
    @Override
    public DeviceVO findVOById(Integer id){
        Device device=findById(id);
        return getDeviceVO(device);
    }
    private void setDeviceFenceIdNone(Device device){
        device.setFenceId(0);
        deviceMapper.updateByPrimaryKeySelective(device);
    }
    @Override
    public void setDeviceFenceId(FenceDeviceReq fenceDeviceReq) {
        Integer deviceId=fenceDeviceReq.getDeviceid();
        Device device=new Device();
        device.setId(fenceDeviceReq.getDeviceid());
        device.setFenceId(fenceDeviceReq.getFenceid());
        deviceMapper.updateByPrimaryKeySelective(device);
    }

    @Override
    public PageInfo getList(Integer page, Integer limit, DeviceParam deviceParam){
        PageHelper.startPage(page,limit);
        List<Device> deviceList=deviceMapper.selectList(deviceParam);
        List<DeviceVO> deviceVOList=deviceListToDeviceVOList(deviceList);
        PageInfo devicePageInfo=new PageInfo<>(deviceList);

        devicePageInfo.setList(deviceVOList);

        return devicePageInfo;
    }
    @Override
    public Device findById(Integer id){
        Device device=deviceMapper.selectByPrimaryKey(id);
        return device;
    }
    private List<DeviceVO> deviceListToDeviceVOList(List<Device> deviceList) {
        List<DeviceVO> deviceVOList=new ArrayList<>();
        for (int i = 0; i < deviceList.size(); i++) {
            Device device =  deviceList.get(i);
            deviceVOList.add(getDeviceVO(device));

        }
        return deviceVOList;
    }

    private DeviceVO getDeviceVO(Device device) {
        if(device==null){
            return null;
        }else{
            DeviceVO deviceVO=new DeviceVO();
            BeanUtils.copyProperties(device,deviceVO);
            deviceVO.setMinprice((float)device.getMinprice()/100);
            Agent agent=agentService.getById(device.getAgentId());
            deviceVO.setAgent_id(device.getAgentId());
            deviceVO.setFence_id(device.getFenceId());
            deviceVO.setAgentInfo(agent);
            deviceVO.setAgentName(agent.getUsername());
            if(ServerHandler.channelMap.containsKey(device.getImei())){
                deviceVO.setIsonline(1);
            }else{
                deviceVO.setIsonline(0);
            }

            deviceVO.setFreeTime(MonthDataUtils.getMinite(device.getLastusetime()));

            return deviceVO;
        }
    }

    /**
     * 删除
     * @param id 通过ID
     */
    @Override
    public void delete(Integer id){
        Device oldDevice=deviceMapper.selectByPrimaryKey(id);
        if(oldDevice==null){
            throw new CarException(CarExceptionEnum.DELETE_FAILED);
        }
        int count=deviceMapper.deleteByPrimaryKey(id);

        if(count==0){
            throw new CarException(CarExceptionEnum.DELETE_FAILED);
        }
    }
    @Override
    public void update(Device device){
        Device oldDevice=findByName(device.getName());
        if(oldDevice!=null && oldDevice.getId()!=device.getId()){
            throw new CarException(CarExceptionEnum.NAME_EXIST);
        }
        Device oldDeviceImei=findByImei(device.getImei());
        if(oldDeviceImei!=null && oldDeviceImei.getId()!=device.getId()){
            throw new CarException(CarExceptionEnum.IMEI_EXIST);
        }
        device.setMinprice(device.getMinprice()*100);
        deviceMapper.updateByPrimaryKeySelective(device);
    }

    @Override
    public void add(Device device){
        Device oldDevice=findByName(device.getName());
        if(oldDevice!=null){
            throw new CarException(CarExceptionEnum.NAME_EXIST);
        }
        Device oldDeviceImei=findByImei(device.getImei());
        if(oldDeviceImei!=null){
            throw new CarException(CarExceptionEnum.IMEI_EXIST);
        }
        device.setMinprice(device.getMinprice()*100);

        int count=deviceMapper.insert(device);
        if(count==0){
            throw new CarException(CarExceptionEnum.INSERT_FAILED);
        }
    }
    @Override
    public Device findByName(String name){
        Device device=deviceMapper.findByName(name);
        return device;
    }
    @Override
    public Device findByImei(String imei){
        Device device=deviceMapper.findByImei(imei);
        return device;
    }
    @Override
    public Integer getFenceId(Integer id){
        Device device=deviceMapper.selectByPrimaryKey(id);
        return device.getFenceId();
    }
    @Override
    public void checkImei(String imei){
        if(imei.length()!=15){
            throw new CarException(CarExceptionEnum.IMEI_ERROR);
        }
        Device currentDevice=this.findByImei(imei);
        if(currentDevice!=null){
            if(currentDevice.getFenceId()==0){
                throw new CarException(CarExceptionEnum.DEVICE_NO_FENCE);
            }
            if(currentDevice.getStatus()==1){
                if(ServerHandler.channelMap.containsKey(imei)) {

                }else{
                    throw new CarException(CarExceptionEnum.DEVICE_NOT_ONLINE);
                }
            }else{
                throw new CarException(CarExceptionEnum.DEVICE_STATUS_ERROR);
            }
        }else{
            throw new CarException(CarExceptionEnum.IMEI_ERROR);
        }
    }
    public void updateStatus(Integer id, int status){
        Device device=new Device();
        device.setId(id);
        device.setStatus(status);
        deviceMapper.updateByPrimaryKeySelective(device);
    }

}
